"""
RedFire Framework - 服务注册中心

提供简化的服务注册和依赖注入机制，替代复杂的DI容器。
支持单例、工厂和实例注册模式。
"""

import inspect
import logging
from typing import Any, Dict, Type, Callable, Optional, TypeVar, Union
from functools import wraps

logger = logging.getLogger(__name__)

T = TypeVar('T')

class ServiceRegistry:
    """服务注册中心
    
    提供轻量级的服务注册和依赖注入功能。
    """

    def __init__(self):
        self._services: Dict[str, Any] = {}
        self._singletons: Dict[str, Any] = {}
        self._factories: Dict[str, Callable] = {}
        self._initializers: Dict[str, Callable] = {}

    def register_instance(self, name: str, instance: Any) -> None:
        """
        注册服务实例

        Args:
            name: 服务名称
            instance: 服务实例
        """
        self._services[name] = instance
        logger.debug(f"Registered service instance: {name}")

    def register_singleton(self, name: str, factory: Callable[[], T]) -> None:
        """
        注册单例服务

        Args:
            name: 服务名称
            factory: 工厂函数
        """
        self._factories[name] = factory
        logger.debug(f"Registered singleton service: {name}")

    def register_factory(self, name: str, factory: Callable) -> None:
        """
        注册工厂函数（每次调用都创建新实例）

        Args:
            name: 服务名称
            factory: 工厂函数
        """
        self._factories[name] = factory
        logger.debug(f"Registered factory service: {name}")

    def register_class(self, name: str, cls: Type[T], *args, **kwargs) -> None:
        """
        注册类（单例模式）

        Args:
            name: 服务名称
            cls: 类型
            *args: 构造参数
            **kwargs: 构造关键字参数
        """
        def factory():
            return cls(*args, **kwargs)
        
        self.register_singleton(name, factory)

    def get(self, name: str) -> Any:
        """
        获取服务实例

        Args:
            name: 服务名称

        Returns:
            服务实例

        Raises:
            KeyError: 服务未注册
        """
        # 检查直接实例
        if name in self._services:
            return self._services[name]

        # 检查单例
        if name in self._singletons:
            return self._singletons[name]

        # 检查工厂
        if name in self._factories:
            factory = self._factories[name]
            
            # 如果是单例，缓存结果
            if name not in self._services:  # 不是直接注册的实例
                instance = factory()
                self._singletons[name] = instance
                return instance
            else:
                # 每次创建新实例
                return factory()

        raise KeyError(f"Service '{name}' not registered")

    def get_optional(self, name: str, default: Any = None) -> Any:
        """
        获取可选服务实例

        Args:
            name: 服务名称
            default: 默认值

        Returns:
            服务实例或默认值
        """
        try:
            return self.get(name)
        except KeyError:
            return default

    def has(self, name: str) -> bool:
        """
        检查服务是否已注册

        Args:
            name: 服务名称

        Returns:
            是否已注册
        """
        return (name in self._services or 
                name in self._singletons or 
                name in self._factories)

    def unregister(self, name: str) -> None:
        """
        注销服务

        Args:
            name: 服务名称
        """
        self._services.pop(name, None)
        self._singletons.pop(name, None)
        self._factories.pop(name, None)
        logger.debug(f"Unregistered service: {name}")

    def clear(self) -> None:
        """清空所有注册的服务"""
        self._services.clear()
        self._singletons.clear()
        self._factories.clear()
        logger.debug("Cleared all registered services")

    def list_services(self) -> list[str]:
        """
        列出所有注册的服务名称

        Returns:
            服务名称列表
        """
        all_services = set()
        all_services.update(self._services.keys())
        all_services.update(self._singletons.keys())
        all_services.update(self._factories.keys())
        return list(all_services)

    async def initialize_async_services(self) -> None:
        """初始化异步服务"""
        for name, initializer in self._initializers.items():
            try:
                if inspect.iscoroutinefunction(initializer):
                    await initializer()
                else:
                    initializer()
                logger.debug(f"Initialized async service: {name}")
            except Exception as e:
                logger.error(f"Failed to initialize service {name}: {e}")
                raise

    def register_initializer(self, name: str, initializer: Callable) -> None:
        """
        注册服务初始化器

        Args:
            name: 服务名称
            initializer: 初始化函数
        """
        self._initializers[name] = initializer
        logger.debug(f"Registered initializer for service: {name}")


# 全局服务注册中心
_global_registry: Optional[ServiceRegistry] = None


def get_registry() -> ServiceRegistry:
    """获取全局服务注册中心"""
    global _global_registry
    if _global_registry is None:
        _global_registry = ServiceRegistry()
    return _global_registry


def set_registry(registry: ServiceRegistry) -> None:
    """设置全局服务注册中心"""
    global _global_registry
    _global_registry = registry


# 装饰器支持
def service(name: str = None, singleton: bool = True):
    """
    服务注册装饰器

    Args:
        name: 服务名称，默认使用类名
        singleton: 是否单例模式
    """
    def decorator(cls):
        service_name = name or cls.__name__.lower()
        registry = get_registry()
        
        if singleton:
            registry.register_singleton(service_name, cls)
        else:
            registry.register_factory(service_name, cls)
        
        return cls
    
    return decorator


def inject(service_name: str):
    """
    依赖注入装饰器

    Args:
        service_name: 服务名称
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            registry = get_registry()
            service_instance = registry.get(service_name)
            return func(service_instance, *args, **kwargs)
        return wrapper
    return decorator


# 便利函数
def register_service(name: str, service: Any) -> None:
    """注册服务实例"""
    get_registry().register_instance(name, service)


def get_service(name: str) -> Any:
    """获取服务实例"""
    return get_registry().get(name)


def has_service(name: str) -> bool:
    """检查服务是否存在"""
    return get_registry().has(name)
